﻿using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using ScFramework.Core;
using UnityEngine.Tilemaps;
using Newtonsoft.Json;


public class MapEditManager : LogicModuleBase<InputManager,MessageManager>
{
    public readonly static string pathSave = System.IO.Path.Combine(Application.dataPath+"/Resources/Text/Map/", "mapData.json");
    private SceneData sceneData = new SceneData();

    private List<Tuple<ElementState, Vector2>> terrianWithoutSerialized = new List<Tuple<ElementState, Vector2>>();
    private List<WaterData> fluidWithoutSerialized = new List<WaterData>();

    //private Dictionary<BelongingSystem, List<string>> mapDic = new Dictionary<BelongingSystem, List<string>>();

    private GameObject tilemapGO = GameObject.Find("Tilemap00");
    Dictionary<string, BelongingSystem> sysDic = new Dictionary<string, BelongingSystem>
    {
        {"water",  BelongingSystem.Fluid},
        {"soil", BelongingSystem.Ground },
        {"wood", BelongingSystem.Ground },
        {"metal", BelongingSystem.Ground },
        {"glass", BelongingSystem.Ground },
        {"ice", BelongingSystem.Ground },
    };

    private delegate void TileMapInstruct(Vector3 pos, string name);
    public override void OnInit(object args)
    {
        base.OnInit(args);
        Debug.Log("MAPEDIT READY");
        
        tilemapGO.SetActive(false);
        //mapDic.Add(BelongingSystem.Ground, terrianWithoutSerialized);
        //mapDic.Add(BelongingSystem.Fluid, fluidWithoutSerialized);
    }

    private void PackMapData(Vector3 pos,  string name)
    {
        if(sysDic[name] == BelongingSystem.Fluid)
        {
            fluidWithoutSerialized.Add(new WaterData { blood = 100, elementState = (ElementState)Enum.Parse(typeof(ElementState), name) , pos = pos, isNeedInstance = default, pointToNext = default});
        }
        else
        {
            terrianWithoutSerialized.Add(new Tuple<ElementState, Vector2>((ElementState)Enum.Parse(typeof(ElementState), name), pos));
        }
        //SysModule1.Get<MapEvent>().DispatchMessage(MapEvent.MapPack, this, new MapInstanceArgs { sys = sysDic[name], pos = pos, name = name }, AddList );
    }
    /*private void AddList(object sender, EventArgs e)
    {
        if(e==null)
        {
            return;
        }
        var dataToAdd = e as MapPackArgs;
        if(dataToAdd.sys == BelongingSystem.Fluid)
        {
            fluidWithoutSerialized.Add(dataToAdd.data);
        }
        else
        {
            terrianWithoutSerialized.Add(dataToAdd.data);
        }
    }*/

    private void MapInstantiate(Vector3 pos, string name)
    {
        SysModule1.Get<MapEvent>().DispatchMessage(MapEvent.MapCreate, this, new MapInstanceArgs { sys = sysDic[name], pos = pos, name = name });
    }

    private void MapDataCurrent(bool LoadFromScene,  TileMapInstruct instruct )
    {
        var tileMap = tilemapGO.GetComponent<Tilemap>();
        if (tileMap == null)
        {
            Debug.LogError("Terrian System : 不存在 Tilemap");
            return;
        }
        if (LoadFromScene)
        {
            var bounds = tileMap.cellBounds;
            for (int x = bounds.xMin;  x <= bounds.xMax;  x++)
            {
                for (int y = bounds.yMin;  y <= bounds.yMax;  y++)
                {
                    for (int z = bounds.zMin;  z <= bounds.zMax;  z++)
                    {
                        Sprite sp = tileMap.GetSprite(new Vector3Int(x, y, z));
                        if (sp != null)
                        {
                            var pos = tileMap.GetCellCenterWorld(new Vector3Int(x, y, z));
                            var name = sp.name.Split('_')[0];
                            instruct(pos, name);
                        }
                    }
                }
            }
            SysModule1.Get<MapEvent>().DispatchMessage(MapEvent.MapCreateOver, this);
        }
    }
    public override void Update()
    {
        base.FixedUpdate();
        //F1 实例化地图中的物体
        if (Input.GetKeyDown(KeyCode.F1))
        {
            Debug.Log("Tilemap Instantiate");
            MapDataCurrent(true, MapInstantiate);
        }

        //F2 保存Tilemap数据到硬盘
        else if (Input.GetKeyDown(KeyCode.F2))
        {
            Debug.Log("Tilemap Save");
            terrianWithoutSerialized.Clear();
            fluidWithoutSerialized.Clear();
            MapDataCurrent(true, PackMapData);
            sceneData = new SceneData();

            sceneData.sysDatas.Add(BelongingSystem.Ground, JsonConvert.SerializeObject(terrianWithoutSerialized));
            sceneData.sysDatas.Add(BelongingSystem.Fluid, JsonConvert.SerializeObject(fluidWithoutSerialized));

            string dataJson = JsonConvert.SerializeObject(sceneData);
            System.IO.File.Create(pathSave).Dispose();
            System.IO.StreamWriter sw = new System.IO.StreamWriter(pathSave);
            sw.Write(dataJson);
            sw.Close();
        }

        //F3 保存当前实例化的状态
        if(Input.GetKeyDown(KeyCode.F3))
        {
            Debug.Log("Scene Save");
            SysModule1.Get<MapEvent>().DispatchMessage(MapEvent.MapSave, this, null);
        }

        //F4 读档 将存档实例化
        if(Input.GetKeyDown(KeyCode.F4))
        {
            Debug.Log("Load Document");
            System.IO.StreamReader sr = new System.IO.StreamReader(pathSave);
            string content = string.Empty;
            content = sr.ReadToEnd();
            sr.Close();
            var parse = JsonConvert.DeserializeObject<SceneData>(content);
            SysModule1.Get<MapEvent>().DispatchMessage(MapEvent.MapLoad, this, new MapLoadArgs { datas = parse.sysDatas[BelongingSystem.Fluid], sys = BelongingSystem.Fluid });
            SysModule1.Get<MapEvent>().DispatchMessage(MapEvent.MapLoad, this, new MapLoadArgs { datas = parse.sysDatas[BelongingSystem.Ground], sys = BelongingSystem.Ground });
        }

        //F10 召唤Tilemap
        if(Input.GetKeyDown(KeyCode.F10))
        {
            Debug.Log("Tilemap on");
            tilemapGO.SetActive(true);
        }

        //F11 遣散Tilemap
        if (Input.GetKeyDown(KeyCode.F11))
        {
            Debug.Log("Tilemap off");
            tilemapGO.SetActive(false);
        }

        //F12 删除当前实例的所有地图块
        if(Input.GetKeyDown(KeyCode.F12))
        {
            Debug.Log("Tilemap Clear");
            SysModule1.Get<MapEvent>().DispatchMessage(MapEvent.MapClear, this);
        }
    }
}
public class MapArgs : EventArgs
{
    public Tuple<BelongingSystem, string> obj;
}
public class MapInstanceArgs : EventArgs
{
    public Vector3 pos;
    public BelongingSystem sys;
    public string name;
}
public class MapLoadArgs : EventArgs
{
    public string datas;
    public BelongingSystem sys;
}

/*public class MapPackArgs : EventArgs
{
    public ElementState elem;
    public Vector2 pos;
    public BelongingSystem sys;
}*/

public enum MapEvent
{
    MapCreate,
    MapPack,
    MapLoad,
    MapSave, 
    MapClear, 
    MapCreateOver
}